home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -seriously_amiga- / cd-rom / acdb / src / acdb_cd.e < prev    next >
Text File  |  1999-04-28  |  16KB  |  675 lines

  1. OPT MODULE,OSVERSION=37
  2. OPT PREPROCESS,REG=5
  3.  
  4. /*
  5.  *-- AutoRev header do NOT edit!!
  6.  *
  7.  *   Project         :   ACDB (AMIGA CD Base) - program obsîugujâcy CDDB
  8.  *   File            :   acdb_cd.e
  9.  *   Description     :   obsîuga CD przez SCSI
  10.  *   Copyright       :   ©1998-1999, Piotr Gapiïski
  11.  *   Author          :   Piotr Gapiïski
  12.  *   Creation Date   :   10.03.99
  13.  *   Current version :   1.0
  14.  *   Translator      :   AmigaE v3.3a
  15.  *
  16.  *-- REVISION HISTORY
  17.  *
  18.  *   1.0 (10.03.99)
  19.  *    o   reorganizacja procedur - lepsze ukrywanie danych i wydzielenie
  20.  *        interfejsu uûytkownika
  21.  *
  22.  *   0.1 (22.12.98)
  23.  *    o   pierwsza wersja (BETA)
  24.  *        obsîuga SCSI oparta na X3T9.2 WORKING DRAFT (7-SEP-93)
  25.  *
  26.  */
  27.  
  28.  
  29. MODULE 'exec/memory','exec/ports','exec/devices','exec/io','devices/scsidisk'
  30. MODULE 'exec/nodes','dos/dos'
  31. MODULE '*acdb_debug','*acdb_gui'
  32.  
  33.   #ifdef DEBUG
  34.     MODULE 'tools/debug'
  35.     #define D(a,b) kputfmt(a,b)
  36.   #endif
  37.   #ifndef DEBUG
  38.     #define D(a,b)
  39.   #endif
  40.  
  41.   ->-
  42.   ->- komendy SCSI (6, 10 i 12 bajtowe)
  43.   ->-
  44.  
  45.   OBJECT scsicmd6
  46.       opcode    :CHAR
  47.       b1        :CHAR
  48.       b2        :CHAR
  49.       b3        :CHAR
  50.       b4        :CHAR
  51.       control   :CHAR
  52.   ENDOBJECT
  53.   OBJECT scsicmd10
  54.       opcode    :CHAR
  55.       b1        :CHAR
  56.       b2        :CHAR
  57.       b3        :CHAR
  58.       b4        :CHAR
  59.       b5        :CHAR
  60.       b6        :CHAR
  61.       b7        :CHAR
  62.       b8        :CHAR
  63.       control   :CHAR
  64.   ENDOBJECT
  65.   OBJECT scsicmd12
  66.       opcode    :CHAR
  67.       b1        :CHAR
  68.       b2        :CHAR
  69.       b3        :CHAR
  70.       b4        :CHAR
  71.       b5        :CHAR
  72.       b6        :CHAR
  73.       b7        :CHAR
  74.       b8        :CHAR
  75.       b9        :CHAR
  76.       b10       :CHAR
  77.       control   :CHAR
  78.   ENDOBJECT
  79.  
  80.   ->-
  81.   ->- track na CD (minuta, sekunda i ramka rozpoczëcia utworu)
  82.   ->-
  83.   OBJECT msf
  84.       min       :LONG
  85.       sec       :LONG
  86.       frm       :LONG
  87.   ENDOBJECT
  88.  
  89.  
  90.   CONST SCSI_CMD_TUR                   = $00,
  91.         SCSI_CMD_RZU                   = $01,
  92.         SCSI_CMD_RQS                   = $03,
  93.         SCSI_CMD_FMU                   = $04,
  94.         SCSI_CMD_RAB                   = $07,
  95.         SCSI_CMD_RD                    = $08,
  96.         SCSI_CMD_WR                    = $0A,
  97.         SCSI_CMD_SK                    = $0B,
  98.         SCSI_CMD_INQ                   = $12,
  99.         SCSI_CMD_MSL                   = $15,
  100.         SCSI_CMD_RU                    = $16,
  101.         SCSI_CMD_RLU                   = $17,
  102.         SCSI_CMD_MSE                   = $1A,
  103.         SCSI_CMD_SSU                   = $1B,
  104.         SCSI_CMD_RDI                   = $1C,
  105.         SCSI_CMD_SDI                   = $1D,
  106.         SCSI_CMD_PAMR                  = $1E,
  107.         SCSI_CMD_RCP                   = $25,
  108.         SCSI_CMD_RXT                   = $28,
  109.         SCSI_CMD_WXT                   = $2A,
  110.         SCSI_CMD_SKX                   = $2B,
  111.         SCSI_CMD_WVF                   = $2E,
  112.         SCSI_CMD_VF                    = $2F,
  113.         SCSI_CMD_RDD                   = $37,
  114.         SCSI_CMD_WDB                   = $3B,
  115.         SCSI_CMD_RDB                   = $3C
  116.  
  117.   CONST SCSI_CMD_COPY                  = $18,
  118.         SCSI_CMD_COMPARE               = $39,
  119.         SCSI_CMD_COPYANDVERIFY         = $3A,
  120.         SCSI_CMD_CHGEDEF               = $40,
  121.         SCSI_CMD_READSUBCHANNEL        = $42,
  122.         SCSI_CMD_READTOC               = $43,
  123.         SCSI_CMD_READHEADER            = $44,
  124.         SCSI_CMD_PLAYAUDIO12           = $A5,
  125.         SCSI_CMD_PLAYAUDIOTRACKINDEX   = $48,
  126.         SCSI_CMD_PAUSERESUME           = $4B
  127.  
  128.   CONST SENSE_LEN       = 252,
  129.         MAX_DATA_LEN    = 252,
  130.         MAX_TOC_LEN     = 804
  131.  
  132.   DEF scsidata:PTR TO CHAR, scsisense:PTR TO CHAR, tocbuffer:PTR TO CHAR
  133.   DEF scsimp:PTR TO mp, scsio:PTR TO iostd
  134.   DEF scsidevice:PTR TO CHAR, scsiunit:LONG
  135.  
  136.   EXPORT OBJECT cdinfo OF ln        ->- obiekt opisujâcy wîaôciwoôci pîyty kompaktowej
  137.   PRIVATE
  138.     cdtoc[100]    :ARRAY OF msf     ->- TOC pîyty w formacie MSF
  139.     idname[20]    :ARRAY OF CHAR    ->- nazwa pliku ID kompaktu
  140.     tracks        :LONG             ->- ile ôcieûek na pîycie
  141.     time          :LONG             ->- czas pîyty w sekundach
  142.     cddb          :LONG             ->- identyfikator CDDB
  143.   ENDOBJECT
  144.  
  145.  
  146.  
  147. EXPORT PROC cdSetup(device:PTR TO CHAR, unit) HANDLE
  148.  
  149.   ->-
  150.   ->- inicjalizacja urzâdzenia SCSI obsîugiwanego przez device
  151.   ->- dev_name/dev_id
  152.   ->- dane wejôciowe nie sâ zapamiëtywane (buforowane)!
  153.   ->- zwraca TRUE/FALSE
  154.   ->-
  155.  
  156.   DEF data:PTR TO CHAR, error
  157.  
  158.   ->-
  159.   ->- zaalokuj sense, TOC i bufory
  160.   ->- ustaw wskaúniki
  161.   ->-
  162.  
  163.   scsidevice := device
  164.   scsiunit := unit
  165.   data := AllocVec((MAX_DATA_LEN + MAX_TOC_LEN + SENSE_LEN), (MEMF_CHIP OR MEMF_CLEAR))
  166.   IF (data = NIL) THEN RETURN FALSE
  167.  
  168.   scsidata  := data
  169.   scsisense := (data + MAX_DATA_LEN)
  170.   tocbuffer := (scsisense + MAX_TOC_LEN)
  171.  
  172.   ->-
  173.   ->- utwórz port i request
  174.   ->-
  175.  
  176.   scsimp := CreateMsgPort()
  177.   IF (scsimp = FALSE) THEN Raise('Unable to create message port!')
  178.   scsio := CreateIORequest(scsimp, (SIZEOF iostd))
  179.   IF (scsio = FALSE) THEN Raise('Unable to create IO request!')
  180.  
  181.   ->-
  182.   ->- otwórz ûâdany device/unit
  183.   ->-
  184.  
  185.   error := OpenDevice(scsidevice, scsiunit, scsio, 0)
  186.   IF (error) THEN Throw('Unable to open %s, unit %ld (error %ld)!', [scsidevice, scsiunit, error, NIL])
  187.   RETURN TRUE
  188.  
  189. EXCEPT
  190.   ->- IF (exception) THEN WriteF('\s!\n', stringFmt(exception, exceptioninfo))
  191.   cdCleanUp()
  192. ENDPROC FALSE
  193.  
  194.  
  195.  
  196. EXPORT PROC cdCleanUp()
  197.  
  198.   ->-
  199.   ->- procedura zwalniajâca wszystkie zaalkowane przez scsiSetup()
  200.   ->- zasoby
  201.   ->- nie zwraca ûadnych wartoôci
  202.   ->-
  203.  
  204.   DEF msg
  205.  
  206.   IF (scsio)
  207.  
  208.     ->-
  209.     ->- scsio,device jest AUTOMATYCZNIE niszczone podczas CloseDevice()
  210.     ->-
  211.  
  212.     IF (scsio.device) THEN CloseDevice(scsio)
  213.     DeleteIORequest(scsio)
  214.   ENDIF
  215.   IF (scsimp)
  216.  
  217.     ->-
  218.     ->- przed usuniëciem portu naleûy pozbyê sië wszystkich zgromadzonych w nim
  219.     ->- wiadomoôci (przy wyîâczonym multitaskingu)
  220.     ->-
  221.  
  222.     Forbid()
  223.     WHILE msg := GetMsg(scsimp) DO ReplyMsg(msg)
  224.     DeleteMsgPort(scsimp)
  225.     Permit()
  226.   ENDIF
  227.   IF (scsidata) THEN FreeVec(scsidata)
  228. ENDPROC
  229.  
  230.  
  231. EXPORT PROC cdRawInfo() HANDLE
  232.  
  233.   ->-
  234.   ->- procedura allokujâca pamiëê na strukturë cdinfo
  235.   ->- brak inicjalizacji
  236.   ->- procedura zwraca wskaúnik na strukturë lub NIL
  237.   ->-
  238.  
  239.   DEF cd=NIL:PTR TO cdinfo
  240.  
  241.   NEW cd
  242. EXCEPT DO
  243. ENDPROC cd
  244.  
  245.  
  246.  
  247. EXPORT PROC cdCreateInfo() HANDLE
  248.  
  249.   ->-
  250.   ->- procedura wypeîniajâca strukturë cdinfo danymi dla dysku aktualnie
  251.   ->- znajdujâcego sië w napëdzie (najpierw testowana jest fizycna obecnoôê dysku)
  252.   ->- zwraca wskaúnik na zainicjowanâ strukturë cdinfo lub NIL
  253.   ->-
  254.  
  255.   DEF cd=NIL:PTR TO cdinfo
  256.  
  257.  
  258.   ->-
  259.   ->- TOC i iloôê ôcieûek
  260.   ->-
  261.  
  262.   IF (cd := cdRawInfo())=NIL THEN Raise()
  263.   cd.tracks := readtocmsf(cd.cdtoc)
  264.   IF (cd.tracks = 0) THEN Raise('Cannot read TOC!')
  265.  
  266.   ->-
  267.   ->- CDDB i time
  268.   ->-
  269.  
  270.   D('[CDCREATEINFO] make cd struct\n', NIL)
  271.   cd.cddb := cddb(cd.tracks, cd.cdtoc)
  272.  
  273.   ->-
  274.   ->- tutaj (chyba) nie moûna uûyê funkcji cdTime() - nie sprawdzaîem
  275.   ->- ale to poniûej dziaîa
  276.   ->-
  277.  
  278.   cd.time := (
  279.                ((cd.cdtoc[cd.tracks].min * 60) + cd.cdtoc[cd.tracks].sec) -
  280.                ((cd.cdtoc[0].min * 60) + cd.cdtoc[0].sec)
  281.              )
  282.   IF fileid(cd.idname)=FALSE THEN Raise('Cannot compute CDID file name!')
  283.   RETURN cd
  284.  
  285. EXCEPT
  286.   IF (cd) THEN cdFreeInfo(cd)
  287.   D('[CDCREATEINFO] error \s\n', [exception, NIL])
  288. ENDPROC NIL
  289.  
  290.  
  291.  
  292. EXPORT PROC cdFreeInfo(cd:PTR TO cdinfo)
  293.  
  294.   ->-
  295.   ->- procedura zwalniajâca caîkowitâ pamiëê zajmowanâ przez opis pîyty kompaktowej
  296.   ->- nie zwraca ûadnych wartoôci
  297.   ->-
  298.   ->-
  299.  
  300.   D('[CDFREEINFO] dispose cd struct\n', NIL)
  301.   END cd
  302. ENDPROC
  303.  
  304.  
  305.  
  306. EXPORT PROC cdWriteInfo(cd:PTR TO cdinfo, handle)
  307.  
  308.   ->-
  309.   ->- procedura zapisujâca identyfikator pîyty do pobrania
  310.   ->- wymaga podania otwartego handle do pliku
  311.   ->- procedura nie zamyka przekazanego deskryptora pliku
  312.   ->- zwraca TRUE/FALSE
  313.   ->-
  314.  
  315.   DEF rc, size, ws
  316.  
  317.   IF (handle)
  318.  
  319.     ->-
  320.     ->- zapis danych do pliku
  321.     ->- dodatkowo nastâpi sprawdzenie poprawnoôci zapisu
  322.     ->-
  323.  
  324.     D('[CDWRITEINFO] write cd to handle $\h\n', [handle, NIL])
  325.     size := (SIZEOF cdinfo) - (SIZEOF ln)
  326.     ws := Write(handle, cd + (SIZEOF ln), size)
  327.     rc := IF (ws = size) THEN TRUE ELSE FALSE
  328.  
  329.   ELSE
  330.     rc := FALSE
  331.   ENDIF
  332. ENDPROC rc
  333.  
  334.  
  335.  
  336. EXPORT PROC cdReadInfo(cd:PTR TO cdinfo, handle)
  337.  
  338.   ->-
  339.   ->- procedura odczytujâca identyfikator pîyty do pobrania
  340.   ->- wymaga podania otwartego handle do pliku
  341.   ->- procedura nie zamyka przekazanego deskryptora pliku
  342.   ->- zwraca TRUE/FALSE
  343.   ->-
  344.  
  345.   DEF rc, size, rd
  346.  
  347.   IF (handle)
  348.  
  349.     ->-
  350.     ->- odczyt danych do pliku
  351.     ->- dodatkowo nastâpi sprawdzenie poprawnoôci odczytu
  352.     ->-
  353.  
  354.     D('[CDREADINFO] read cd from handle $\h\n', [handle, NIL])
  355.     size := (SIZEOF cdinfo) - (SIZEOF ln)
  356.     rd := Read(handle, cd + (SIZEOF ln), size)
  357.     rc := IF (rd = size) THEN TRUE ELSE FALSE
  358.   ELSE
  359.     rc := FALSE
  360.   ENDIF
  361. ENDPROC rc
  362.  
  363.  
  364.  
  365. EXPORT PROC cdInquire()
  366.  
  367.   ->-
  368.   ->- procedura pobierajâca i wyôwietlajâca dane zapisane w CD-ROM'ie przez producenta
  369.   ->- nie zwraca ûadnych wartoôci
  370.   ->-
  371.  
  372.   DEF command:PTR TO scsicmd6, rc
  373.  
  374.   command    := [SCSI_CMD_INQ,0,0,0,0,0]:scsicmd6
  375.   command.b4 := MAX_DATA_LEN
  376.  
  377.   rc := doscsicmd(scsidata, MAX_DATA_LEN, command, (SIZEOF scsicmd6), (SCSIF_READ OR SCSIF_AUTOSENSE))
  378.   IF (rc = 0)
  379.  
  380.     ->-
  381.     ->- pokaû odebrane dane
  382.     ->-
  383.  
  384.     guiInformUser('Software driver: %s, unit %ld\nType (5): CD-ROM device\nVendor: %.8s\nProduct: %.16s\nRevision: %.4s',
  385.                ' _Ok ',
  386.                [scsidevice, scsiunit, (scsidata + 8), (scsidata + 16), (scsidata + 32), NIL])
  387.   ELSE
  388.     DisplayBeep(NIL)
  389.   ENDIF
  390. ENDPROC
  391.  
  392.  
  393.  
  394. EXPORT PROC cdCheck()
  395.  
  396.   ->-
  397.   ->- procedura sprawdzajâca czy device/unit faktycznie obsîuguje CD-ROM
  398.   ->- zwraca TRUE/FALSE
  399.   ->-
  400.  
  401.   DEF command:PTR TO scsicmd6, rc
  402.  
  403.   command    := [SCSI_CMD_INQ,0,0,0,0,0]:scsicmd6
  404.   command.b4 := MAX_DATA_LEN
  405.  
  406.   rc := doscsicmd(scsidata, MAX_DATA_LEN, command, (SIZEOF scsicmd6), (SCSIF_READ OR SCSIF_AUTOSENSE))
  407.   IF (rc=0)
  408.  
  409.     ->-
  410.     ->- musi zwróciê 5, w przeciwnym razie nie jest to CD-ROM
  411.     ->-
  412.  
  413.     RETURN IF (scsidata[] AND $1F)=5 THEN TRUE ELSE FALSE
  414.   ELSE
  415.     DisplayBeep(NIL)
  416.   ENDIF
  417. ENDPROC FALSE
  418.  
  419.  
  420.  
  421. EXPORT PROC cdEject(eject=TRUE)
  422.  
  423.   ->-
  424.   ->- procedura zamykajâca/otwierajâca kieszeï napëdu
  425.   ->- zwraca 0/kod bîëdu (< 0)
  426.   ->-
  427.  
  428.   DEF command:PTR TO scsicmd6, rc
  429.  
  430.   command := IF (eject) THEN [SCSI_CMD_SSU,0,0,0,2,0]:scsicmd6 ELSE [SCSI_CMD_SSU,0,0,0,3,0]:scsicmd6
  431.   rc := doscsicmd(scsidata, MAX_DATA_LEN, command, (SIZEOF scsicmd6), (SCSIF_READ OR SCSIF_AUTOSENSE))
  432. ENDPROC rc
  433.  
  434.  
  435.  
  436. EXPORT PROC cdTrackTime(cd:PTR TO cdinfo, track)
  437.  
  438.   ->-
  439.   ->- procedura pobierajâca czas trwania okreôlonego utworu
  440.   ->- zwraca czas w sekundach lub FALSE
  441.   ->-
  442.  
  443.   DEF time
  444.  
  445.   IF (track >= cd.tracks) THEN RETURN FALSE
  446.   time := ((cd.cdtoc[track + 1].frm) - (cd.cdtoc[track].frm))/75
  447. ENDPROC time
  448.  
  449.  
  450.  
  451. EXPORT PROC cdTime(cd:PTR TO cdinfo)
  452.  
  453.   ->-
  454.   ->- procedura pobierajâca czas trwania caîej pîyty
  455.   ->- zwraca czas w sekundach
  456.   ->-
  457.  
  458.   DEF time
  459.  
  460.   ->- time := ((cd.cdtoc[cd.tracks].frm) - (cd.cdtoc[0].frm))/75
  461.   time := cd.time
  462. ENDPROC time
  463.  
  464.  
  465.  
  466. EXPORT PROC cdTrackOffset(cd:PTR TO cdinfo, track)
  467.  
  468.   ->-
  469.   ->- procedura pobierajâca offset utworu wzglëdem poczâtku pîyty
  470.   ->- zwraca offset lub FALSE
  471.   ->-
  472.  
  473.   DEF rc
  474.  
  475.   IF (track >= cd.tracks) THEN RETURN FALSE
  476.   rc := cd.cdtoc[track].frm
  477. ENDPROC rc
  478.  
  479.  
  480.  
  481. EXPORT PROC cdFileId(cd: PTR TO cdinfo)
  482.  
  483.   ->-
  484.   ->- procedura pobierajâca nazwë identyfikatora pod jakâ zostanie
  485.   ->- zapisany plik opisu pîyty
  486.   ->-
  487.  
  488.   DEF name
  489.  
  490.   name := IF (cd) THEN cd.idname ELSE NIL
  491. ENDPROC name
  492.  
  493.  
  494.  
  495. EXPORT PROC cdId(cd:PTR TO cdinfo) IS cd.cddb
  496. EXPORT PROC cdTracks(cd:PTR TO cdinfo) IS cd.tracks
  497.  
  498.  
  499.  
  500.   ->-
  501.   ->- prywatne
  502.   ->- procedury wspomagajâce obsîugë CD-ROM'u
  503.   ->-
  504.  
  505.  
  506.  
  507. PROC readtocmsf(msf:PTR TO msf)
  508.  
  509.   ->-
  510.   ->- procedura odczytujâca TOC (table of contents) CD-ROMu - 804bajty
  511.   ->- w formacie MSF (min, sec, frame)
  512.   ->- procedura nie rozróûnia tracków AUDIO od DATA
  513.   ->- zwraca liczbë ôcieûek na pîycie oraz kopiuje TOC pîyty do przekazanego
  514.   ->- jako parametr bufora (o wielkoôci 100 * SIZEOF msf)
  515.   ->-
  516.  
  517.   DEF command:PTR TO scsicmd10, rc
  518.   DEF tocsize, tocptr:PTR TO CHAR, tocnumtracks=0
  519.   DEF cdtoc[100]:ARRAY OF msf
  520.  
  521.   command    := [SCSI_CMD_READTOC,0,0,0,0,0,0,$03,$24,0]:scsicmd10
  522.   command.b1 := 2  ->- MSF
  523.   rc := doscsicmd(tocbuffer, MAX_TOC_LEN, command, (SIZEOF scsicmd10), (SCSIF_READ OR SCSIF_AUTOSENSE))
  524.   IF (rc=0)
  525.  
  526.     ->-
  527.     ->- oblicz realnâ wielkoôê TOC
  528.     ->-
  529.  
  530.     tocsize := Shl(tocbuffer[], 8) + tocbuffer[1]
  531.     IF (tocsize >= 2) THEN tocsize := tocsize - 2
  532.     tocptr := tocbuffer + 4
  533.     tocnumtracks := 0
  534.  
  535.     WHILE (tocptr < (tocbuffer + 4 + tocsize))
  536.  
  537.       ->-
  538.       ->- pobieraj wszystkie ôcieûki bez wzglëdu na to czy jest to audio czy data!
  539.       ->- ôcieûki sâ opisane w formacie MSF
  540.       ->-
  541.  
  542.       cdtoc[tocnumtracks].min := tocptr[5]
  543.       cdtoc[tocnumtracks].sec := tocptr[6]
  544.       cdtoc[tocnumtracks].frm := ((tocptr[5]*60)+(tocptr[6]))*75+tocptr[7]
  545.       tocptr := tocptr + 8
  546.       tocnumtracks++
  547.     ENDWHILE
  548.     tocnumtracks--
  549.   ENDIF
  550.  
  551.   ->-
  552.   ->- skopiuj dane przechowywane lokalnie do bufora wskazywanego przez msf
  553.   ->-
  554.  
  555.   CopyMem(cdtoc, msf, (100 * SIZEOF msf))
  556. ENDPROC tocnumtracks
  557.  
  558.  
  559.  
  560. PROC fileid(cdid: PTR TO CHAR)
  561.  
  562.   ->-
  563.   ->- procedura tworzâca ID pliku do CDplayera (format zgodny z SCDP)
  564.   ->- wynik kopiuje do bufora przekazanego do procedury
  565.   ->- brak rozróûniania ôcieûek audio i data
  566.   ->- zwraca TRUE/FALSE oraz gdy TRUE to kopiuje identyfikator do bufora przekazanego
  567.   ->- jako parametr (minimum 20 bajtów)
  568.   ->-
  569.  
  570.   DEF command:PTR TO scsicmd10, rc
  571.   DEF tocsize, tocptr:PTR TO CHAR, tocnumtracks=0
  572.   DEF toctrackaddr[256]: ARRAY OF LONG
  573.   DEF tmp[20]:STRING
  574.  
  575.   command := [SCSI_CMD_READTOC,0,0,0,0,0,0,$03,$24,0]:scsicmd10
  576.   rc := doscsicmd(tocbuffer, MAX_TOC_LEN, command, (SIZEOF scsicmd10), (SCSIF_READ OR SCSIF_AUTOSENSE))
  577.   IF (rc = 0)
  578.  
  579.     ->-
  580.     ->- oblicz realnâ wielkoôê TOC
  581.     ->-
  582.  
  583.     tocsize := Shl(tocbuffer[], 8) + tocbuffer[1]
  584.     IF (tocsize >= 2) THEN tocsize := tocsize - 2
  585.     tocptr := tocbuffer + 4
  586.     tocnumtracks := 0
  587.  
  588.     WHILE (tocptr < (tocbuffer + 4 + tocsize))
  589.  
  590.       ->-
  591.       ->- obliczenie identyfikatora
  592.       ->-
  593.  
  594.       toctrackaddr[tocnumtracks] := (Shl(tocptr[4], 24) OR Shl(tocptr[5], 16) OR Shl(tocptr[6], 8) OR (tocptr[7]))
  595.  
  596.       ->-
  597.       ->- brak rozróûniania ôcieûek audio i data
  598.       ->-
  599.       ->- tocflags[tocnumtracks] := IF ((tocptr+1) AND $04) THEN 1 ELSE 0
  600.       ->-
  601.  
  602.       tocnumtracks++
  603.       tocptr := tocptr + 8
  604.     ENDWHILE
  605.     tocnumtracks--
  606.  
  607.     stringFmt(tmp, 'ID%02ld%06lx%06lx', [tocnumtracks, toctrackaddr[2], toctrackaddr[tocnumtracks], NIL])
  608.     AstrCopy(cdid, tmp, 20)
  609.   ENDIF
  610. ENDPROC (rc = 0)
  611.  
  612.  
  613.  
  614. PROC doscsicmd(data:PTR TO CHAR,datasize,cmd:PTR TO CHAR,cmdsize,flags)
  615.  
  616.   ->-
  617.   ->- procedura wykonujâca okreôlonâ komendë SCSI
  618.   ->- zwraca 0 w przypadku sukcesu lub kod bîëdu (< 0)
  619.   ->-
  620.  
  621.   DEF scsicmd:scsicmd
  622.  
  623.   scsio.length        := (SIZEOF scsicmd)
  624.   scsio.data          := scsicmd
  625.   scsio.command       := HD_SCSICMD
  626.  
  627.   scsicmd.data        := data
  628.   scsicmd.length      := datasize
  629.   scsicmd.senseactual := 0
  630.   scsicmd.senselength := SENSE_LEN
  631.   scsicmd.sensedata   := scsisense
  632.   scsicmd.command     := cmd
  633.   scsicmd.cmdlength   := cmdsize
  634.   scsicmd.flags       := flags
  635.   scsicmd.status      := 0
  636.  
  637.   DoIO(scsio)
  638. ENDPROC (scsio.error)
  639.  
  640.  
  641.  
  642. PROC cddb(trks, cdtoc:PTR TO msf)
  643.  
  644.   ->-
  645.   ->- procedura wyznaczajâce CDID kompaktu na potrzeby CDDB
  646.   ->- zaczerpniëta z CDDB howto (www.cddb.com)
  647.   ->- obliczony identyfikator MUSI byê przedstawiany jako 8-mio cyfrowa liczba
  648.   ->- zapisana w kodzie ASCII (w kodzie szesnastkowym)
  649.   ->-
  650.  
  651.   DEF i=0, t=0, n=0
  652.  
  653.   WHILE (i < trks)
  654.     n := n + cddbsum(((cdtoc[i].min) * 60) + (cdtoc[i].sec))
  655.     i++
  656.   ENDWHILE
  657.   n := Shl(Mod(n,255), 24)
  658.   t := (((cdtoc[trks].min)*60)+(cdtoc[trks].sec)) - (((cdtoc[0].min)*60)+(cdtoc[0].sec))
  659.   t := Shl(t, 8)
  660. ENDPROC (n OR t OR trks)
  661. PROC cddbsum(n: LONG)
  662.  
  663.   ->-
  664.   ->- procedura pomocnicza wyznaczania CDDB
  665.   ->-
  666.  
  667.   DEF ret=0, a
  668.  
  669.   WHILE (n > 0)
  670.     a := Mod(n, 10)
  671.     ret := (ret + a)
  672.     n := (n / 10)
  673.   ENDWHILE
  674. ENDPROC ret
  675.